Skip to main content

OpenDSR API

Subsets implements the OpenDSR v2 specification as a Data Processor. Data Controllers can submit erasure requests through this API to exercise data subject rights under GDPR and CCPA.

Base URL: https://platform.subsets.com/api/opendsr

Authentication

All endpoints require a valid Bearer token. Include it in the Authorization header:

Authorization: Bearer <token>

Two authentication methods are supported:

Use the OAuth 2.0 Client Credentials Grant to obtain a token. Subsets will provision a client_id and client_secret for your organization.

curl -X POST https://auth.subsets.ai/oauth/token \
-H "Content-Type: application/json" \
-d '{
"client_id": "<your_client_id>",
"client_secret": "<your_client_secret>",
"audience": "https://api.subsets.ai",
"grant_type": "client_credentials"
}'

The response contains an access_token to use as the Bearer token. Tokens are short-lived; request a new one when it expires.

Admin user token

Users with admin role can also authenticate using the Bearer token obtained by SSO login.

Contact your Subsets account manager to obtain credentials.

Supported capabilities

  • Request types: erasure only
  • Identity types: email (raw), controller_customer_id (raw)
  • Regulations: gdpr, ccpa

Endpoints

Discovery

Returns the capabilities of this OpenDSR processor.

GET https://platform.subsets.com/api/opendsr/discovery

Response 200

{
"api_version": "2.0",
"supported_identities": [
{ "identity_type": "email", "identity_format": "raw" },
{ "identity_type": "controller_customer_id", "identity_format": "raw" }
],
"supported_subject_request_types": ["erasure"]
}

Create request

Submit a new data subject erasure request.

POST https://platform.subsets.com/api/opendsr/requests

Request body

FieldTypeRequiredDescription
regulationstringYes"gdpr" or "ccpa"
subject_request_idUUID v4YesUnique ID generated by the Controller
subject_request_typestringYesMust be "erasure"
submitted_timeRFC 3339YesTime of the original data subject request
subject_identitiesarrayNoArray of identity objects (see below)
status_callback_urlsarrayNonot yet supported
api_versionstringNoDesired API version ("2.0")

Identity object

FieldTypeRequiredDescription
identity_typestringYes"email" or "controller_customer_id"
identity_valuestringYesThe identity value
identity_formatstringYes"raw"

Example request

curl -X POST https://api.subsets.com/api/opendsr/requests \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{
"regulation": "gdpr",
"subject_request_id": "a7551968-d5d6-44b2-9831-815ac9017798",
"subject_request_type": "erasure",
"submitted_time": "2026-04-01T12:00:00Z",
"subject_identities": [
{
"identity_type": "email",
"identity_value": "johndoe@example.com",
"identity_format": "raw"
}
]
}'

Response 201

{
"controller_id": "d4f7a8b2-...",
"expected_completion_time": "2026-05-01T12:00:00Z",
"received_time": "2026-04-01T12:00:01Z",
"encoded_request": "<base64>",
"subject_request_id": "a7551968-d5d6-44b2-9831-815ac9017798",
"processor_signature": "not-yet-implemented"
}

Response headers: X-OpenDSR-Processor-Domain, X-OpenDSR-Signature

Error responses

StatusCondition
400Invalid request or unsupported subject_request_type
409A request with this subject_request_id already exists

Get request status

Check the status of a previously submitted request.

GET https://platform.subsets.com/api/opendsr/requests/{subject_request_id}

Response 200

{
"controller_id": "d4f7a8b2-...",
"expected_completion_time": "2026-05-01T12:00:00Z",
"subject_request_id": "a7551968-d5d6-44b2-9831-815ac9017798",
"request_status": "pending",
"api_version": "2.0"
}

Possible statuses

StatusDescription
pendingRequest received, not yet started
in_progressRequest is being processed
completedRequest has been fulfilled
cancelledRequest was cancelled

Error responses

StatusCondition
404Request not found

Cancel request

Cancel a pending erasure request. Only requests with pending status can be cancelled.

DELETE https://platform.subsets.com/api/opendsr/requests/{subject_request_id}

Response 202

{
"controller_id": "d4f7a8b2-...",
"received_time": "2026-04-02T10:00:00Z",
"subject_request_id": "a7551968-d5d6-44b2-9831-815ac9017798",
"processor_signature": "not-yet-implemented",
"api_version": "2.0"
}

Error responses

StatusCondition
400Request is not in pending status
404Request not found

Error format

All error responses follow this structure:

{
"error": {
"code": 400,
"message": "Description of what went wrong"
}
}

Processing timeline

Subsets aims to fulfill erasure requests within 30 days of submission. The expected_completion_time in the response reflects this timeline. You can poll the status endpoint to track progress.